import akka.actor.ActorRef;
import akka.actor.UntypedActor;
import akka.dispatch.Future;

/**
 * Body scanner for the airport
 * 
 * @author Peter-John Rowe
 * @author mja2637
 */
public class BodyScanner extends UntypedActor {
	
	/** Line that Scanner belongs to */
	protected final int lineIndex;
	/** Reference to security station */
	protected final ActorRef security;
	private ActorRef queue;
	/** Stock indentation for messages from this actor */
	private final String INDENTATION = "    ";

	/**
	 * BodyScanner constructor.
	 * 
	 * @param index
	 * @param security
	 */
	public BodyScanner(int index, ActorRef security) {
		this.lineIndex = index;
		this.security = security;
		
	}

	/**
	 * Set the reference to the queue.
	 * 
	 * @param queue
	 */
	public void setQueue(ActorRef queue) {
		this.queue = queue;
	}
	
	/**
	 * Scans the passenger and reports the scan-pass boolean to the Security station.
	 * 
	 * @param p - the Passenger being scanned
	 */
	protected void scan(Passenger p) {
		// Get scan inspection result
		boolean scanPassBoolean = Math.random() > 0.20;
		// Sends report message to the security station
		sendMessageToSecurity(new Report(p,scanPassBoolean));
		// Tells the queue to send another passenger
		queue.tell(new Next());
		System.out.format(INDENTATION+"Body Scan %d: Next passenger\n", lineIndex);
	}

	/**
	 * Sends report message to the security station in its line.
	 * 
	 * @param rep - Report with passenger as well as the scan pass boolean
	 */
	protected void sendMessageToSecurity(Report rep) {
		// Sends message to the security station
		security.tell(rep);
		String passFail = rep.getScanPassBoolean() ? "passes" : "fails";

		// Passenger pass/fail printout
		System.out.format("%sBody Scan %d: %s %s\n",
				INDENTATION, lineIndex, rep.getPassenger().getName(), passFail);
	}

	@Override
	public void onReceive(Object message) throws Exception {
		// When Passenger message is received
		if (message instanceof Passenger) {
			// Receive passenger printout
			System.out.format("%sBody Scan %d: %s enters\n", 
					INDENTATION, lineIndex, ((Passenger)message).getName());
			// Scans passenger
			scan((Passenger)message);				
		}

		// When Pill message is received
		if (message instanceof Pill) { 
			// Receive close printout
			System.out.format(INDENTATION+"Body Scan %d: Close received\n", lineIndex);

			// Propagates the close message
			security.tell(new Pill());
			// Close printout propagation
			System.out.format(INDENTATION+"Body Scan %d: Close sent to security\n", lineIndex);
			
			// Closes actor
			getContext().stop();
			// Print out that the body scan closed
			System.out.format(INDENTATION+"Body Scan %d: Closed\n", lineIndex);
		}
	}
}// BodyScanner Class
